<?php
/**
 * 每日任务
 */

namespace App\Repositories\Task;

use App\Enums\TaskEnum;
use App\Exceptions\BasicException;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class EveryDayTaskRepository
{
    public $moduleId;

    public $taskExpireTime;

    public function __construct()
    {
        $this->moduleId = TaskEnum::TASK_MODULE_EVERY_DAY;
    }

    // 每日任务是否处于激活状态
    public function isActive()
    {
        return app("repo_task")->isModuleActive($this->moduleId);
    }

    // 获取用户每日任务过期时间
    public function getTaskExpireTime()
    {
        if ($this->taskExpireTime) {
            return $this->taskExpireTime;
        }

        $this->taskExpireTime = strtotime(date("Y-m-d") . " + " . TaskEnum::TASK_DELAY_DAY_EVERY_DAY . " days") - 1;

        return $this->taskExpireTime;
    }

    // 解析每日任务配置
    public function parseEveryDayConfig($allTaskConfig, $userId)
    {
        // 起始日期距今天数
        $startDate = Carbon::createFromFormat("Y-m-d", TaskEnum::TASK_EVERY_DAY_START_DATE);
        $curDate   = Carbon::create();

        $diffDays = $startDate->diffInDays($curDate);
        $result   = [];
        foreach ($allTaskConfig as $taskConfig) {
            if ($taskConfig['cycle_days'] && $diffDays % $taskConfig['cycle_days'] == 0) {
                $now      = time();
                $result[] = [
                    "name"           => $taskConfig['name'],
                    "desc"           => $taskConfig['desc'],
                    "unique_id"      => md5($this->moduleId . $userId . $taskConfig['id'] . $this->getTaskExpireTime()),
                    "user_id"        => $userId,
                    "module_id"      => $this->moduleId,
                    "type_id"        => $taskConfig['type_id'],
                    "task_config_id" => $taskConfig['id'],
                    "reward_id"      => $taskConfig['reward_id'],
                    "reward_number"  => $taskConfig['reward_number'],
                    "reward_type"    => $taskConfig['reward_type'],
                    "expire_time"    => $this->getTaskExpireTime(),
                    "target_limit"   => $taskConfig['target_limit'],
                    "status"         => TaskEnum::TASK_USER_UN_FINISH,
                    "is_deleted"     => 0,
                    "add_time"       => $now,
                    "update_time"    => $now,
                ];
            }
        }

        return $result;
    }

    // 格式化每日任务
    public function formatEveryDayTaskFromConfig($userId)
    {
        $allTaskConfig = app("repo_task")->getAllTaskConfig($this->moduleId);

        $result = $this->parseEveryDayConfig($allTaskConfig, $userId);
        if (!$result) {
            return [];
        }

        return $result;
    }

    // 下发每日任务
    public function issueTask($userId)
    {
        $redisKey = sprintf(TaskEnum::TASK_USER_EVERY_DAY_HAS_ISSUE, $userId);

        $lock = Redis::setnx($redisKey, 1);
        if (!$lock) {
            return true;
        }
        Redis::expireat($redisKey, $this->getTaskExpireTime());

        DB::connection("mysql")->transaction(function () use ($userId) {
            // 将已经发放过的每日任务都置为删除
            app("model_task_user")->where([
                "user_id"    => $userId,
                "module_id"  => $this->moduleId,
                "is_deleted" => 0
            ])->update([
                "update_time" => time(),
                "is_deleted"  => 1,
            ]);

            $insertArr = $this->formatEveryDayTaskFromConfig($userId);

            if (!$insertArr) {
                return true;
            }
            $affectRows = DB::connection("mysql")->table(app('model_task_user')->getTable())->insert($insertArr);

            if (!$affectRows) {
                throw new BasicException(15006);
            }
        }, 5);

        return true;
    }

    // 获得用户的每日任务列表
    public function getUserTaskList($userId)
    {
        $allTask = app("repo_task")->getUserTaskList($userId, $this->moduleId);

        $randomHolderId = app("repo_room")->getRandomHolderId();
        $userRoom       = app('model_user_room')->where("user_id", $userId)->first();
        $result         = [];
        foreach ($allTask as $userTask) {
            $linkData = app("repo_task")->getLinkDataFromTask($userTask, $randomHolderId, $userRoom);

            $result[] = [
                "task_id"     => $userTask->id,
                "task_name"   => $userTask->name,
                "current"     => $userTask->task_degree,
                "target"      => $userTask->target_limit,
                "type_id"     => $userTask->type_id,
                "task_desc"   => $userTask->desc,
                "link_type"   => $linkData['link_type'],
                "link_param"  => $linkData['link_param'],
                "task_status" => $userTask->status,
                "reward"      => app("repo_task")->getRewardDataFromTask($userTask),
            ];
        }
        return $result;
    }

}
